package com.huawei.admins.platform.gateway.core.server.gateway;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ContextPathCompositeHandler;
import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.DispatcherHandler;

import java.util.Collections;

@AutoConfiguration(after = { WebFluxAutoConfiguration.class })
@ConditionalOnClass({ DispatcherHandler.class, HttpHandler.class })
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
@ConditionalOnMissingBean(HttpHandler.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
public class GatewayHandlerConfiguration {

    @Configuration(proxyBeanMethods = false)
    public static class AnnotationConfig {

        private final ApplicationContext applicationContext;

        public AnnotationConfig(ApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
        }

        @Bean
        public HttpHandler httpHandler(ObjectProvider<WebFluxProperties> propsProvider) {
            GatewayHttpHandler httpHandler = GatewayHttpHandlerBuilder.applicationContext(this.applicationContext).build();
            WebFluxProperties properties = propsProvider.getIfAvailable();
            if (properties != null && StringUtils.hasText(properties.getBasePath())) {
                return new ContextPathCompositeHandler(Collections.singletonMap(properties.getBasePath(), httpHandler));
            }
            return httpHandler;
        }

        @Bean
        public GatewayWebHandler gatewayWebHandler() {
            return new GatewayWebHandler();
        }

    }

}
